<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <title>绘制矩形网格</title>
    <script type="text/javascript" src="../js/floatNum.js"></script>
    <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
    <style>
        html, body, #container {
            margin: 0;
            height: 100%;
        }

        .input-item-text {
            width: 7rem;
        }
    </style>
</head>
<body>
<div id="container"></div>
<div class="input-card">
    <label style='color:grey'>绘制矩形网格</label>
    <div class="input-item">
        <div class="input-item-prepend">
            <span class="input-item-text">行政级别</span>
        </div>
        <select id="level">
            <option value="district">district</option>
            <option value="city">city</option>
            <option value="province">province</option>
        </select>

    </div>
    <div class="input-item">
        <div class="input-item-prepend">
            <span class="input-item-text">名称/adcode</span>
        </div>
        <input id='district' type="text" value='历下区'>
    </div>
    <div class="input-item">
        <div class="input-item-prepend">
            <span class="input-item-text">经线距离/M</span>
        </div>
        <input id='lngDistance' type="text" value='5000'>
    </div>
    <div class="input-item">
        <div class="input-item-prepend">
            <span class="input-item-text">纬线距离/M</span>
        </div>
        <input id='latDistance' type="text" value='5000'>
    </div>
    <input id="draw" type="button" class="btn" value="查询"/>
</div>
<script type="text/javascript"
        src="https://webapi.amap.com/maps?v=1.4.15&key=【您的key】&plugin=AMap.DistrictSearch"></script>
<script type="text/javascript">
    //初始化地图对象，加载地图
    const map = new AMap.Map("container", {
        resizeEnable: true
    });

    let district = null;
    let polygons = [];
    let polygons2 = [];

    function drawBounds() {
        //加载行政区划插件
        if (!district) {
            //实例化DistrictSearch
            let opts = {
                subdistrict: 0,   //获取边界不需要返回下级行政区
                extensions: 'all',  //返回行政区边界坐标组等具体信息
                level: 'district'  //查询行政级别为 市
            };
            district = new AMap.DistrictSearch(opts);
        }
        //行政区查询
        district.setLevel(document.getElementById('level').value);
        district.search(document.getElementById('district').value, function (status, result) {
            //清除上次结果
            map.remove(polygons);
            map.remove(polygons2);
            polygons = [];
            const bounds = result.districtList[0].boundaries;
            if (bounds.length > 0) {
                for (let i = 0, l = bounds.length; i < l; i++) {
                    //行政区域边界
                    let polygon = new AMap.Polygon({
                        strokeWeight: 1,
                        path: bounds[i],
                        fillOpacity: 0.4,
                        fillColor: '#80d8ff',
                        strokeColor: '#0091ea'
                    });
                    polygons.push(polygon);

                    //经度
                    let lng = [];
                    //纬度
                    let lat = [];
                    let arr = bounds[i].toString().split(",");
                    for (let j = 0, k = arr.length; j < k; j++) {
                        if (j % 2 == 0) {
                            lng.push(arr[j]);
                        } else {
                            lat.push(arr[j]);
                        }
                    }
                    //获取经纬线距离
                    let lngDistance = document.getElementById('lngDistance').value;
                    let latDistance = document.getElementById('latDistance').value;
                    //加载矩形
                    let boundy = rectangle(mathMax(lng), mathMax(lat), mathMin(lng), mathMin(lat), lngDistance, latDistance);
                    rectangleGrid(boundy);
                }
            } else {
                alert("所选区域不存在：" + document.getElementById('district').value);
            }
            map.add(polygons);
            map.setFitView(polygons);//视口自适应
        });
    }

    //绘制矩形网格
    function rectangleGrid(bounds) {
        polygons2 = [];
        for (let i = 0, g = bounds.length; i < g; i++) {
            let rectangle = new AMap.Rectangle({
                bounds: bounds[i],
                strokeColor: '#FF0000',
                strokeWeight: 2,
                strokeOpacity: 0.5,
                strokeDasharray: [30, 10],
                strokeStyle: 'solid',
                fillColor: '',
                fillOpacity: 0.5,
                cursor: 'pointer',
                zIndex: 50,
            });
            polygons2.push(rectangle);
        }
        map.add(polygons2);
        // 缩放地图到合适的视野级别
        map.setFitView(polygons2);//视口自适应
    }


    //计算矩形
    function rectangle(maxLng, maxLat, minLng, minLat, lng, lat) {
        //经纬度：米/度
        const lngMi = 0.00001141;
        const latMi = 0.00000899;
        //经纬度递增数
        const lngInc = lngMi * lng;
        const latInc = latMi * lat;

        //用于返回经纬度对象
        let lngLatArr = [];

        //计算经度(纬度相等)
        while (true) {
            let addLat = accAdd(minLat, latInc);
            if (addLat <= maxLat) {
                extracted(addLat, minLng, maxLng, minLat, lngInc, lngLatArr);
                minLat = addLat;
            } else {
                addLat = maxLat;
                extracted(addLat, minLng, maxLng, minLat, lngInc, lngLatArr);
                break;
            }
        }
        return lngLatArr;
    }

    //计算所需经纬度数据
    function extracted(addLat, minLng, maxLng, minLat, lngInc, lngLatArr) {
        while (true) {
            //经度
            let addLng = accAdd(minLng, lngInc);
            let southWest;
            let northEast;
            let bound;
            if (addLng <= maxLng) {
                southWest = new AMap.LngLat(minLng, minLat);
                northEast = new AMap.LngLat(addLng, addLat);
                bound = new AMap.Bounds(southWest, northEast);
                lngLatArr.push(bound);
                minLng = addLng;
            } else {
                southWest = new AMap.LngLat(minLng, minLat);
                northEast = new AMap.LngLat(maxLng, addLat);
                bound = new AMap.Bounds(southWest, northEast);
                lngLatArr.push(bound);
                break;
            }
        }
    }

    // 查找数组中最小值
    function mathMin(arrs) {
        let min = arrs[0];
        for (let i = 1, g = arrs.length; i < g; i += 1) {
            if (arrs[i] < min) {
                min = arrs[i];
            }
        }
        return min;
    }

    // 在数组中查找最大值
    function mathMax(arrs) {
        let max = arrs[0];
        for (var i = 1, g = arrs.length; i < g; i++) {
            if (arrs[i] > max) {
                max = arrs[i];
            }
        }
        return max;
    }

    //调用方法
    drawBounds();
    document.getElementById('draw').onclick = drawBounds;

    //键盘回车事件
    document.onkeydown = function (event) {
        e = event ? event : (window.event ? window.event : null);
        if (e.keyCode == 13) {
            //执行的方法
            drawBounds();
        }
    };

</script>
</body>
</html>